#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <left4dhooks>
ConVar g_cvDifficulty;

#define PLUGIN_VERSION "1.0"


public Plugin myinfo =
{
	name = "l4d2_witch_damage_replacer",
	author = "豆瓣酱な",
	description = "专家难度下，强制将Witch攻击伤害替换为：站立玩家100伤害/倒地玩家30伤害，并显示为世界伤害来源.",
	version = PLUGIN_VERSION,
	url = "https://gitee.com/sweet-and-sour-bombs/adfvsdsd"
};

public void OnPluginStart()
{
	g_cvDifficulty = FindConVar("z_difficulty");
    
	// 备用检测（某些服务器可能修改ConVar名称）
	if (g_cvDifficulty == null) 
	{
		g_cvDifficulty = FindConVar("mp_gamemode");
	}
    
	HookEvent("player_hurt", Event_PlayerHurt);
}

public void OnClientPutInServer(int client)
{
	SDKHook(client, SDKHook_OnTakeDamageAlive, OnTakeDamage);
}

public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype)
{
	if (IsWitch(attacker) && IsImpossibleMode())
	{
		damage = 0.0;
		RequestFrame(ApplyWorldDamage, GetClientUserId(victim));
		return Plugin_Handled;
	}
	return Plugin_Continue;
}

void ApplyWorldDamage(any userid)
{
	int client = GetClientOfUserId(userid);
	if (IsValidClient(client))
	{
		if (IsPlayerIncapacitated(client))
		{
			SDKHooks_TakeDamage(client, 0, 0, 30.0, DMG_GENERIC);
		}
		else
		{
			SDKHooks_TakeDamage(client, 0, 0, 100.0, DMG_GENERIC);
		}
	}
}

public void Event_PlayerHurt(Event event, const char[] name, bool dontBroadcast)
{
	int attacker = event.GetInt("attacker");
	if (IsWitch(attacker) && IsImpossibleMode())
	{
		event.SetInt("attacker", 0);
		event.SetString("weapon", "world");
	}
}

// 精准识别 Impossible/Expert 难度
bool IsImpossibleMode()
{
	if (g_cvDifficulty == null) return false;
    
	char difficulty[32];
	g_cvDifficulty.GetString(difficulty, sizeof(difficulty));
    
	// 兼容所有可能的专家难度名称（不区分大小写）
	return (StrContains(difficulty, "impossible", false) != -1 || 
	StrContains(difficulty, "expert", false) != -1 ||
	StrContains(difficulty, "专家", false) != -1); // 中文支持
}

bool IsWitch(int entity)
{
	if (entity <= 0 || !IsValidEntity(entity)) return false;
    
	char classname[32];
	GetEntityClassname(entity, classname, sizeof(classname));
	return StrEqual(classname, "witch");
}

bool IsValidClient(int client)
{
	return (client > 0 && client <= MaxClients && IsClientInGame(client) && IsPlayerAlive(client));
}


//倒地的玩家
bool IsPlayerIncapacitated(int client)
{
	return view_as<bool>(GetEntProp(client, Prop_Send, "m_isIncapacitated"));
}